#include "driver_display.h"
#include "driver_nv3041a.h"
 
#include "driver_parallel_interface.h"

#define LCD_INTERFACE_QSPI	0 
#define LCD_INTERFACE_8080	1

#if(LCD_INTERFACE_QSPI==1)

#define NV3041A_MAX_PARA_COUNT							(300)

#define NV3041A_QSPI_INST_CMD_WRITE						(0x02)
#define NV3041A_QSPI_INST_CMD_READ						(0x03)
#define NV3041A_QSPI_INST_1WIRE_PIXEL_WRITE				(0x02)
#define NV3041A_QSPI_INST_4WIRE_PIXEL_WRITE_TYPE1		(0x32)
#define NV3041A_QSPI_INST_4WIRE_PIXEL_WRITE_TYPE2		(0x12)
#define NV3041A_QSPI_SEQ_FINISH_CODE					(0x00)

typedef struct _NV3041A_CMD_DESC {
    uint8_t instruction;
    uint8_t index;
    uint16_t delay;
    uint16_t wordcount;
    uint8_t  payload[NV3041A_MAX_PARA_COUNT];
} NV3041A_CMD_DESC;

static const NV3041A_CMD_DESC NV3041A_PRE_OTP_POWERON_SEQ_CMD[] = {
//    {NV3041A_QSPI_INST_CMD_WRITE, 0x11, 10, 0, {0}},
//    {NV3041A_QSPI_INST_CMD_WRITE, 0x2A, 1, 4, {0x00, 0x00, 0x01, 0x6F}},
//    {NV3041A_QSPI_INST_CMD_WRITE, 0x2B, 1, 4, {0x00, 0x00, 0x01, 0xBF}},
//    {NV3041A_QSPI_INST_CMD_WRITE, 0x44, 1, 2, {0x01, 0xBF}},
//    {NV3041A_QSPI_INST_CMD_WRITE, 0x3A, 1, 1, {0x05}},      // 16bits pixel
//    {NV3041A_QSPI_INST_CMD_WRITE, 0x35, 1, 1, {0x00}},
//    {NV3041A_QSPI_INST_CMD_WRITE, 0x53, 25, 1, {0x20}},
//    {NV3041A_QSPI_INST_CMD_WRITE, 0x29, 1, 0, {0}},

//    {NV3041A_QSPI_INST_CMD_WRITE, 0x51, 1, 1, {0xFF}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xff, 1, 1, { 0xa5,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xE7, 1, 1, { 0x10,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x35, 1, 1, { 0x01,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x3A, 1, 1, { 0x01,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x40, 1, 1, { 0x01,}},
	//{NV3041A_QSPI_INST_CMD_WRITE, 0x41, 1, 1, { 0x03,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x55, 1, 1, { 0x01,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x44, 1, 1, { 0x15,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x45, 1, 1, { 0x15,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x7d, 1, 1, { 0x03,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xc1, 1, 1, { 0xab,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xc2, 1, 1, { 0x17,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xc3, 1, 1, { 0x10,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xc6, 1, 1, { 0x3a,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xc7, 1, 1, { 0x25,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xc8, 1, 1, { 0x11,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x6f, 1, 1, { 0x2f,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x78, 1, 1, { 0x4b,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x7a, 1, 1, { 0x49,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xc9, 1, 1, { 0x00,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x51, 1, 1, { 0x20,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x52, 1, 1, { 0x7c,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x53, 1, 1, { 0x1c,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x54, 1, 1, { 0x77,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x46, 1, 1, { 0x0a,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x47, 1, 1, { 0x2a,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x48, 1, 1, { 0x0a,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x49, 1, 1, { 0x1a,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x56, 1, 1, { 0x43,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x57, 1, 1, { 0x42,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x58, 1, 1, { 0x3c,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x59, 1, 1, { 0x64,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x5a, 1, 1, { 0x41,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x5b, 1, 1, { 0x3c,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x5c, 1, 1, { 0x02,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x5d, 1, 1, { 0x3c,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x5e, 1, 1, { 0x1f,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x60, 1, 1, { 0x80,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x61, 1, 1, { 0x3f,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x62, 1, 1, { 0x21,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x63, 1, 1, { 0x07,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x64, 1, 1, { 0xe0,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x65, 1, 1, { 0x01,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xca, 1, 1, { 0x20,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xcb, 1, 1, { 0x52,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xcc, 1, 1, { 0x10,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xcD, 1, 1, { 0x42,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xD0, 1, 1, { 0x20,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xD1, 1, 1, { 0x52,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xD2, 1, 1, { 0x10,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xD3, 1, 1, { 0x42,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xD4, 1, 1, { 0x0a,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xD5, 1, 1, { 0x32,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xe5, 1, 1, { 0x05,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xe6, 1, 1, { 0x00,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x6e, 1, 1, { 0x14,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x80, 1, 1, { 0x04,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xA0, 1, 1, { 0x00,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x81, 1, 1, { 0x07,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xA1, 1, 1, { 0x05,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x82, 1, 1, { 0x06,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xA2, 1, 1, { 0x04,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x83, 1, 1, { 0x39,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xA3, 1, 1, { 0x39,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x84, 1, 1, { 0x3a,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xA4, 1, 1, { 0x3a,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x85, 1, 1, { 0x3f,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xA5, 1, 1, { 0x3f,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x86, 1, 1, { 0x2c,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xA6, 1, 1, { 0x2a,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x87, 1, 1, { 0x43,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xA7, 1, 1, { 0x47,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x88, 1, 1, { 0x08,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xA8, 1, 1, { 0x08,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x89, 1, 1, { 0x0f,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xA9, 1, 1, { 0x0f,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x8a, 1, 1, { 0x17,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xAa, 1, 1, { 0x17,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x8b, 1, 1, { 0x10,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xAb, 1, 1, { 0x10,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x8c, 1, 1, { 0x16,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xAc, 1, 1, { 0x16,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x8d, 1, 1, { 0x14,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xAd, 1, 1, { 0x14,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x8e, 1, 1, { 0x11,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xAe, 1, 1, { 0x11,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x8f, 1, 1, { 0x14,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xAf, 1, 1, { 0x14,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x90, 1, 1, { 0x06,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xB0, 1, 1, { 0x06,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x91, 1, 1, { 0x0f,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xB1, 1, 1, { 0x0f,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x92, 1, 1, { 0x16,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xB2, 1, 1, { 0x16,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xff, 1, 1, { 0x00,}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x11, 120, 0, {0}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x29, 120, 0, {0}},

    {NV3041A_QSPI_SEQ_FINISH_CODE,	0,	0,	0,	{0}},
};
	




static const NV3041A_CMD_DESC NV3041A_POWEROFF_SEQ_CMD[] = {
    {NV3041A_QSPI_INST_CMD_WRITE, 0x28,	15,	0,	{0}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0x10,	0,	0,	{0}},
    {NV3041A_QSPI_SEQ_FINISH_CODE,	0,	0,	0,	{0}},
};

static const NV3041A_CMD_DESC NV3041A_OTP_WRITE[] = {
	{NV3041A_QSPI_INST_CMD_WRITE, 0xD0,	1000,	2,	{0x01}},
	{NV3041A_QSPI_INST_CMD_WRITE, 0xD0,	10,	2,	{0x00}},
    {NV3041A_QSPI_SEQ_FINISH_CODE,	0,	0,	0,	{0}},
};

#ifdef USE_DMA_LINK_MODE
static DMA_LLI_InitTypeDef *Link_Channel = (void *)0x1fffe000;
#endif

static void write_cmd(uint8_t cmd)
{
    uint8_t spi_data[4];

    spi_data[0] = NV3041A_QSPI_INST_CMD_WRITE;
    spi_data[1] = 0x00;
    spi_data[2] = cmd;
    spi_data[3] = 0x00;

    __DISPLAY_CS_CLEAR();
    spi_master_transmit_X1(&spi_display_handle, (uint16_t *)spi_data, 4);
    __DISPLAY_CS_SET();
}

static void write_buff(uint8_t *buffer, uint8_t len)
{
    __DISPLAY_CS_CLEAR();
    spi_master_transmit_X1(&spi_display_handle, (uint16_t *)buffer, len);
    __DISPLAY_CS_SET();
}

static void read_reg(uint8_t reg, uint8_t *buffer, uint16_t len)
{
    uint8_t spi_data[4];

    spi_data[0] = NV3041A_QSPI_INST_CMD_READ;
    spi_data[1] = 0x00;
    spi_data[2] = reg;
    spi_data[3] = 0x00;

    __DISPLAY_CS_CLEAR();
    spi_master_transmit_X1(&spi_display_handle, (uint16_t *)spi_data, 4);
    spi_master_receive_X1(&spi_display_handle, buffer, len);
    __DISPLAY_CS_SET();
}

static void NV3041A_Reg_Write(const NV3041A_CMD_DESC* cmd)
{
    uint16_t idx = 0;	

    while (cmd[idx].instruction != NV3041A_QSPI_SEQ_FINISH_CODE) 
    {
        uint8_t sdat[cmd[idx].wordcount + 4];

        sdat[0] = cmd[idx].instruction;

        sdat[1] = 0;
        sdat[2] = cmd[idx].index;        // Set in the middle 8 bits ADDR[15:8] of the 24 bits ADDR[23:0]
        sdat[3] = 0;

        for(uint16_t i=0; i<cmd[idx].wordcount; i++)
        {
            sdat[i+4] = cmd[idx].payload[i];
        }

        __DISPLAY_CS_CLEAR();
        spi_master_transmit_X1(&spi_display_handle, sdat, sizeof(sdat));
        __DISPLAY_CS_SET();

        if (cmd[idx].delay != 0) 
        {
            __DISPLAY_DELAY_MS(cmd[idx].delay);
        }		

        idx++;
    }
}

static void NV3041A_Init_Pre_OTP(void)                                
{
	//pull low RESX
	//power on VBAT: VBAT = 3.7V
	//power on VDDI: VDDI = 1.8V
	//pull high VCI_EN: enable VCI = 3.3V
	//delay 10ms
	//pull high RESX: IC reset
	//delay 10ms
    NV3041A_Reg_Write(NV3041A_PRE_OTP_POWERON_SEQ_CMD);
}



static void NV3041A_Power_Off(void)                                
{
    NV3041A_Reg_Write(NV3041A_POWEROFF_SEQ_CMD);
	//delay 100ms
	//pull low RESX
	//delay 10ms
	//pull low VCI_EN: disable VCI
	//power off VDDI
	//power off VBAT
}

static void NV3041A_OTP_Write(void)                                
{
	/*********************************************
	* Register read: 
	* Index: 0xCF (OTP_STATUS)
	* Para: 1 Byte read
	* Check BANK_CHECK_MCS[1:0]:
	* - 00h: No writen, 3 times writable
	* - 01h: 1 time written, 2 times writable
	* - 02h: 2 times written, 1 time writable
	* - 03h: 3 time written, no longer be written
	**********************************************/
	
	//power on VOTP: VOTP = 6V external supply
	//delay 20ms	
    NV3041A_Reg_Write(NV3041A_OTP_WRITE);
	//power off VOTP
	//delay 20ms
	
	/*********************************************
	* OTP status verification: 
	* Index: 0xCF (OTP_STATUS)
	* Para: 3 Bytes read
	* Check PRG_ERR_1:
	* - 0: OK
	* - 1: FAIL
		   OTP rewrite(power off -> power on -> rewrite)
	* Check PRG_ERR_0:
	* - 0: OK
	* - 1: FAIL
		   Not rewrite OTP
	**********************************************/
	
	/* Go to power off sequence */
}

static void sh8601a_read_regs(void)
{
    uint8_t buffer[6];

    read_reg(0x90, buffer, 6);
    read_reg(0x2A, buffer, 4);
    read_reg(0x2B, buffer, 4);
}
#define pixel_size	100*100
uint16_t color_buffer[pixel_size]={0};
void nv3041a_init(void)
{
    __DISPLAY_VCI_CLEAR();
    __DISPLAY_RESET_CLEAR();
    __DISPLAY_DELAY_MS(10);
    __DISPLAY_VCI_SET();
    __DISPLAY_DELAY_MS(10);
    __DISPLAY_RESET_SET();
    __DISPLAY_DELAY_MS(10);

    NV3041A_Init_Pre_OTP();
	extern uint32_t *user_get_display_framebuffer(void);
	uint16_t *buf = (uint16_t*)user_get_display_framebuffer();
	
	nv3041a_set_window(0,100-1,0,100-1);
	for(uint32_t i=0;i<pixel_size;i++)
	{
		color_buffer[i]=0x001f;
	}
	nv3041a_display_dma(pixel_size,16,color_buffer);
	printf("nv3041a_init\r\n");
 	//system_delay_us(2000*1000);
}

void nv3041a_set_window(uint16_t x_s, uint16_t x_e, uint16_t y_s, uint16_t y_e)
{
    uint8_t data[8];
 
    data[0] = 0x02;
    data[1] = 0x00;
    data[2] = 0x2A;
    data[3] = 0x00;
    data[4] = x_s >> 8;
    data[5] = x_s & 0xff;
    data[6] = x_e >> 8;
    data[7] = x_e & 0xff;
    write_buff(data, 8);

    data[0] = 0x02;
    data[1] = 0x00;
    data[2] = 0x2B;
    data[3] = 0x00;    
    data[4] = y_s >> 8;
    data[5] = y_s & 0xff;
    data[6] = y_e >> 8;
    data[7] = y_e & 0xff;
    write_buff(data, 8);

//    write_cmd(0x2c);
}

void nv3041a_display(uint32_t pixel_count, uint8_t pixel_width, void *data)
{
	
    uint8_t frame_size;

    if (pixel_width == 16) {
        frame_size = SPI_FRAME_SIZE_16BIT;
    }
    else if (pixel_width == 32) {
        frame_size = SPI_FRAME_SIZE_24BIT;
    }
    spi_display_handle.Init.Frame_Size              = frame_size;
    spi_display_handle.MultWireParam.Wire_X2X4X8    = Wire_X4;
    spi_display_handle.MultWireParam.InstructLength = INST_8BIT;
    spi_display_handle.MultWireParam.Instruct       = 0x32;
    spi_display_handle.MultWireParam.AddressLength  = ADDR_24BIT;
    spi_display_handle.MultWireParam.Address        = 0x002C00;

    __DISPLAY_CS_CLEAR();
    spi_master_transmit_X2X4X8(&spi_display_handle, data, pixel_count);
    __DISPLAY_CS_SET();

    __SPI_DISABLE(spi_display_handle.SPIx);
    __SPI_DATA_FRAME_SIZE(spi_display_handle.SPIx, SPI_FRAME_SIZE_8BIT);
}

void nv3041a_display_dma(uint32_t pixel_count, uint8_t pixel_width, void *data)
{
//#define USE_DMA_LINK_MODE
    uint8_t spi_trans_width;
    uint32_t dma_sample_count;
    
#ifdef USE_DMA_LINK_MODE
#define DMA_SINGLE_TRANSFER_SIZE       20000
    uint32_t link_count;
    uint32_t i;
    uint32_t link_trans_size;
    dma_LinkParameter_t LinkParameter;
    

    switch (dma_display_handle.Init.Source_Width) {
        case DMA_TRANSFER_WIDTH_32:
            dma_sample_count = pixel_count * pixel_width / 32;
            link_trans_size = 4 * DMA_SINGLE_TRANSFER_SIZE;
            break;
        case DMA_TRANSFER_WIDTH_16:
            dma_sample_count = pixel_count * pixel_width / 16;
            link_trans_size = 2 * DMA_SINGLE_TRANSFER_SIZE;
            break;
        case DMA_TRANSFER_WIDTH_8:
            dma_sample_count = pixel_count * pixel_width / 8;
            link_trans_size = DMA_SINGLE_TRANSFER_SIZE;
            break;
        default:
            return;
    }
    
    link_count = dma_sample_count / DMA_SINGLE_TRANSFER_SIZE;
    if(dma_sample_count % DMA_SINGLE_TRANSFER_SIZE)
    {
        link_count++;
    }
    
    for (i = 0; i < link_count; i++)
    {
        uint8_t all_set = (dma_sample_count <= DMA_SINGLE_TRANSFER_SIZE);
        
        LinkParameter.SrcAddr          = (uint32_t)data + i * link_trans_size;
        LinkParameter.DstAddr          = (uint32_t)&spi_display_handle.SPIx->DR;
        if(all_set)
        {
            LinkParameter.NextLink     = 0;
        }
        else
        {
            LinkParameter.NextLink     = (uint32_t)&Link_Channel[i + 1];
        }
        LinkParameter.Data_Flow             = dma_display_handle.Init.Data_Flow;
        LinkParameter.Request_ID            = dma_display_handle.Init.Request_ID;
        LinkParameter.Source_Master_Sel     = dma_display_handle.Init.Source_Master_Sel;
        LinkParameter.Desination_Master_Sel = dma_display_handle.Init.Desination_Master_Sel;
        LinkParameter.Source_Inc            = dma_display_handle.Init.Source_Inc;
        LinkParameter.Desination_Inc        = dma_display_handle.Init.Desination_Inc;
        LinkParameter.Source_Width          = dma_display_handle.Init.Source_Width;
        LinkParameter.Desination_Width      = dma_display_handle.Init.Desination_Width;
        LinkParameter.Source_Burst_Len      = dma_display_handle.Init.Source_Burst_Len;
        LinkParameter.Desination_Burst_Len  = dma_display_handle.Init.Desination_Burst_Len;
        LinkParameter.Size                  = all_set ? dma_sample_count : DMA_SINGLE_TRANSFER_SIZE;
        LinkParameter.gather_enable         = 0;
        LinkParameter.scatter_enable        = 0;
        dma_sample_count -= DMA_SINGLE_TRANSFER_SIZE;

        dma_linked_list_init(&Link_Channel[i], &LinkParameter);
    }
#else
    switch (dma_display_handle.Init.Source_Width) {
        case DMA_TRANSFER_WIDTH_32:
            dma_sample_count = pixel_count * pixel_width / 32;
            break;
        case DMA_TRANSFER_WIDTH_16:
            dma_sample_count = pixel_count * pixel_width / 16;
            break;
        case DMA_TRANSFER_WIDTH_8:
            dma_sample_count = pixel_count * pixel_width / 8;
            break;
        default:
            return;
    }
#endif

    switch (dma_display_handle.Init.Desination_Width) {
        case DMA_TRANSFER_WIDTH_32:
            spi_trans_width = SPI_FRAME_SIZE_32BIT;
            break;
        case DMA_TRANSFER_WIDTH_16:
            spi_trans_width = SPI_FRAME_SIZE_16BIT;
            break;
        case DMA_TRANSFER_WIDTH_8:
            spi_trans_width = SPI_FRAME_SIZE_8BIT;
            break;
        default:
            return;
    }
    
    spi_display_handle.Init.Frame_Size              = spi_trans_width;
    spi_display_handle.MultWireParam.Wire_X2X4X8    = Wire_X4;
    spi_display_handle.MultWireParam.InstructLength = INST_8BIT;
    spi_display_handle.MultWireParam.Instruct       = 0x32;
    spi_display_handle.MultWireParam.AddressLength  = ADDR_24BIT;
    spi_display_handle.MultWireParam.Address        = 0x002C00;

    __DISPLAY_CS_CLEAR();
    
    __SPI_DISABLE(spi_display_handle.SPIx);
    __SPI_TX_ENDIAN_SET(spi_display_handle.SPIx, TX_RX_Endian_4321);
    __SPI_ENABLE(spi_display_handle.SPIx);
    spi_master_transmit_X2X4X8_DMA(&spi_display_handle);
    
    __SPI_DISABLE(spi_display_handle.SPIx);
    if (spi_trans_width == SPI_FRAME_SIZE_32BIT) {
        __SPI_TX_ENDIAN_SET(spi_display_handle.SPIx, TX_RX_Endian_2143);
    }
    else {
        __SPI_TX_ENDIAN_SET(spi_display_handle.SPIx, TX_RX_Endian_4321);
    }
    __SPI_ENABLE(spi_display_handle.SPIx);
#ifndef USE_DMA_LINK_MODE
    dma_start_IT(&dma_display_handle, (uint32_t)data, (uint32_t)&spi_display_handle.SPIx->DR, dma_sample_count);
#else
    dma_linked_list_start_IT(Link_Channel, &LinkParameter, &dma_display_handle);
#endif
}

void nv3041a_power_off(void)
{
    NV3041A_Power_Off();

    __DISPLAY_DELAY_MS(100);
    __DISPLAY_RESET_CLEAR();
    __DISPLAY_DELAY_MS(10);
    __DISPLAY_VCI_CLEAR();
}

void nv3041a_power_on(void)
{
    __DISPLAY_VCI_CLEAR();
    __DISPLAY_RESET_CLEAR();
    __DISPLAY_DELAY_MS(10);
    __DISPLAY_VCI_SET();
    __DISPLAY_DELAY_MS(10);
    __DISPLAY_RESET_SET();
    __DISPLAY_DELAY_MS(10);

    NV3041A_Init_Pre_OTP();
}

void nv3041a_display_dma_isr(void)
{
    while(__SPI_IS_BUSY(spi_display_handle.SPIx));

    // CS Release
    __DISPLAY_CS_SET();
	
    /* Clear Transfer complete status */
    dma_clear_tfr_Status(&dma_display_handle);
    /* channel Transfer complete interrupt disable */
    dma_tfr_interrupt_disable(&dma_display_handle);

    __SPI_DISABLE(spi_display_handle.SPIx);
    __SPI_TX_ENDIAN_SET(spi_display_handle.SPIx, TX_RX_Endian_4321);
    __SPI_DATA_FRAME_SIZE(spi_display_handle.SPIx, SPI_FRAME_SIZE_8BIT);
}

#elif(LCD_INTERFACE_8080==1)
extern PARALLEL_HandTypeDef hparallel;

static void WriteComm(uint8_t reg)
{
   
	__PARALLEL_CS_SET(hparallel.PARALLELx);
	/* writer cmd */
	Parallel_write_cmd(&hparallel,reg); 
	__PARALLEL_CS_RELEASE(hparallel.PARALLELx);
}
static void WriteData(uint8_t data)
{
	__PARALLEL_CS_SET(hparallel.PARALLELx);
	/* writer cmd */
	Parallel_write_param(&hparallel,data);
	__PARALLEL_CS_RELEASE(hparallel.PARALLELx);
}

static void LCD_READ_DATA(uint8_t reg)
{
	static uint16_t data=0;
	__PARALLEL_CS_SET(hparallel.PARALLELx);
	/* writer cmd */
	
	//Parallel_write_cmd(&hparallel,reg); 
	// Parallel_read_data_cmd(&hparallel,reg,&data,1);
	printf("reg_param:0x%x\r\n",data);
	__PARALLEL_CS_RELEASE(hparallel.PARALLELx);		
}
void display_backlight_set(void)
{
    gpio_write_pin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
}

void display_backlight_clear(void)
{
    gpio_write_pin(GPIOB, GPIO_PIN_3, GPIO_PIN_CLEAR);
}
void nv3041a_set_window(uint16_t x_s, uint16_t x_e, uint16_t y_s, uint16_t y_e)
{
    WriteComm(0x2a);//列地址设置
    WriteData(x_s>>8);
    WriteData(x_s&0xff);
    WriteData(x_e>>8);
    WriteData(x_e&0xff);
    WriteComm(0x2b);//行地址设置
    WriteData(y_s>>8);
    WriteData(y_s&0xff);
    WriteData(y_e>>8);
    WriteData(y_e&0xff);
    WriteComm(0x2c);//储存器写
//    write_cmd(0x2c);
}


void LCD_Fill(uint16_t xsta,uint16_t ysta,uint16_t xend,uint16_t yend,uint16_t color)
{          
	uint16_t i,j,size; 
	nv3041a_set_window(xsta,xend-1,ysta,yend-1);//设置显示范围
	__PARALLEL_CS_SET(hparallel.PARALLELx);
 
	if(hparallel.Init.DataBusSelect == DATA_BUS_8_BIT)
	{
		size=2;
	}else{
		size=2;
	}
	for(i=ysta;i<yend;i++)
	{													   	 	
		for(j=xsta;j<xend;j++)
		{
		//	LCD_WR_DATA(color);
			/* writer data */            
            Parallel_write_data(&hparallel,(uint32_t *)&color,size);
		}
	} 		
	__PARALLEL_CS_RELEASE(hparallel.PARALLELx);	
}
void nv3041a_display(uint32_t pixel_count, uint8_t pixel_width, void *data)
{
    uint32_t frame_size=0;
	
	if (pixel_width == 8) {
		frame_size = (pixel_count*4);
    }
    if (pixel_width == 16) {
      //  frame_size = SPI_FRAME_SIZE_16BIT;
		frame_size = (pixel_count*2);
    }
    else if (pixel_width == 32) {
		frame_size = (pixel_count);
    }
	
	__PARALLEL_CS_SET(hparallel.PARALLELx);
    //Parallel_write_param(&hparallel,data);
	Parallel_write_data(&hparallel,data,(frame_size));
	//while(__PARALLEL_IS_BUS_BUSY(hparallel.PARALLELx)); 
    __PARALLEL_CS_RELEASE(hparallel.PARALLELx);
	
}

void nv3041a_display_dma(uint32_t pixel_count, uint8_t pixel_width, void *data)
{
     uint8_t dma_trans_width=0;
     uint32_t dma_sample_count=0;
    switch (dma_display_handle.Init.Source_Width) {
        case DMA_TRANSFER_WIDTH_32:
			//272x480 16 
            dma_sample_count = pixel_count * pixel_width / 32;
			//dma_sample_count=dma_sample_count*4;
            break;
        case DMA_TRANSFER_WIDTH_16:
            dma_sample_count = pixel_count * pixel_width / 16;
		//	dma_sample_count=dma_sample_count*2;
            break;
        case DMA_TRANSFER_WIDTH_8:
            dma_sample_count = pixel_count * pixel_width / 8;
		//	dma_sample_count=dma_sample_count;
            break;
        default:
            return;
    }
//	switch(hparallel.Init.DataBusSelect)
//	{
//		case DATA_BUS_8_BIT:
//			dma_trans_width = 2;
//		break;
//		
//		case DATA_BUS_16_BIT:
//			dma_trans_width=2;
//		break;
//	}
	dma_sample_count=dma_sample_count*2;
    __PARALLEL_CS_SET(hparallel.PARALLELx);
    __PARALLEL_SET_WR_LEN(hparallel.PARALLELx,dma_sample_count);
    dma_start_IT(&dma_display_handle, (uint32_t)data, (uint32_t)&hparallel.PARALLELx->TX_FIFO, (dma_sample_count));
}

void nv3041a_display_dma_isr(void)
{
    #if 0
    while(__SPI_IS_BUSY(spi_display_handle.SPIx));
    // CS Release
    __DISPLAY_CS_SET();
	
    /* Clear Transfer complete status */
    dma_clear_tfr_Status(&dma_display_handle);
    /* channel Transfer complete interrupt disable */
    dma_tfr_interrupt_disable(&dma_display_handle);

    __SPI_DISABLE(spi_display_handle.SPIx);
    __SPI_TX_ENDIAN_SET(spi_display_handle.SPIx, TX_RX_Endian_4321);
    __SPI_DATA_FRAME_SIZE(spi_display_handle.SPIx, SPI_FRAME_SIZE_8BIT);
    #endif
	//printf("nv3041a_display_dma_isr1\r\n");
    while(!( __PARALLEL_INT_STATUS(hparallel.PARALLELx)&INT_TXFIFO_EMPTY));
    __PARALLEL_CS_RELEASE(hparallel.PARALLELx);
    /* Clear Transfer complete status */
    dma_clear_tfr_Status(&dma_display_handle);
    /* channel Transfer complete interrupt disable */
    dma_tfr_interrupt_disable(&dma_display_handle);
	//printf("nv3041a_display_dma_isr2\r\n");
}

#define pixel_size	100*100
uint16_t color_buffer[pixel_size]={0};

void nv3041a_init(void)
{
	display_backlight_clear();
	
	#if 0
    WriteComm(0xff);
	WriteData(0xa5);
	WriteComm(0xE7);//TE_output_en
	WriteData(0x10);
	WriteComm(0x35);//TE_ interface_en
	WriteData(0x01);
	WriteComm(0x3A);
	WriteData(0x01);//00---666//01--565
	WriteComm(0x40);
	WriteData(0x01); //01:IPS/00:TN
	WriteComm(0x41);
	WriteData(0x03);//01--8bit//03--16bit
	WriteComm(0x55);
	WriteData(0x01);
	WriteComm(0x44);//VBP
	WriteData(0x15);//21NVu NV3041A-01

	WriteComm(0x45);//VFP
	WriteData(0x15);//21
	WriteComm(0x7d);//vdds_trim[2:0]
	WriteData(0x03);//2.07V
	WriteComm(0xc1);//avdd_clp_en avdd_clp[1:0] avcl_clp_en avcl_clp[1:0]
	WriteData(0xab);//6.74V/-5.16V
	WriteComm(0xc2);//vgh_clp_en vgl_clp[2:0]
	WriteData(0x17);
	WriteComm(0xc3);//vgl_clp_en vgl_clp[2:0]
	WriteData(0x10);//-10.951
	WriteComm(0xc6);//avdd_ratio_sel avcl_ratio_sel vgh_ratio_sel[1:0] vgl_ratio_sel[1:0]
	WriteData(0x3a);//35
	WriteComm(0xc7);//mv_clk_sel[1:0] avdd_clk_sel[1:0] avcl_clk_sel[1:0]
	WriteData(0x25); //2e
	WriteComm(0xc8);// VGL_CLK_sel
	WriteData(0x11);
	WriteComm(0x6f);// user_gvdd
	WriteData(0x2f);
	WriteComm(0x78);// user_gvcl
	WriteData(0x4b);
	//WriteComm(0x7a);// user_vgsp
	//WriteData(0x5f);
	//test
	WriteComm(0x7a);// user_vgsp
	WriteData(0x49);
	WriteComm(0xc9);
	WriteData(0x00);
	//gate_ed
	WriteComm(0x51);//gate_st_o[7:0]
	//WriteData(0x4b);
	WriteData(0x20);
	WriteComm(0x52);//gate_ed_o[7:0]
	WriteData(0x7c);
	WriteComm(0x53);//gate_st_e[7:0]
	//WriteData(0x45);
	WriteData(0x1c);
	WriteComm(0x54);//gate_ed_e[7:0]
	WriteData(0x77);
	////sorce oldNVu NV3041A-01

	WriteComm(0x46);//fsm_hbp_o[5:0]
	WriteData(0x0a);
	WriteComm(0x47);//fsm_hfp_o[5:0]
	WriteData(0x2a);
	WriteComm(0x48);//fsm_hbp_e[5:0]
	WriteData(0x0a);
	WriteComm(0x49);//fsm_hfp_e[5:0]
	WriteData(0x1a);
	WriteComm(0x56);//src_ld_wd[1:0] src_ld_st[5:0]
	WriteData(0x43);
	WriteComm(0x57);//pn_cs_en src_cs_st[5:0]
	WriteData(0x42);
	WriteComm(0x58);//src_cs_p_wd[6:0]
	WriteData(0x3c);
	WriteComm(0x59);//src_cs_n_wd[6:0]
	WriteData(0x64);
	WriteComm(0x5a);//src_pchg_st_o[6:0]
	WriteData(0x41);
	WriteComm(0x5b);//src_pchg_wd_o[6:0]
	WriteData(0x3c);
	WriteComm(0x5c);//src_pchg_st_e[6:0]
	WriteData(0x02);
	WriteComm(0x5d);//src_pchg_wd_e[6:0]
	WriteData(0x3c);
	WriteComm(0x5e);//src_pol_sw[7:0]
	WriteData(0x1f);
	WriteComm(0x60);//src_op_st_o[7:0]
	WriteData(0x80);
	WriteComm(0x61);//src_op_st_e[7:0]
	WriteData(0x3f);
	WriteComm(0x62);//src_op_ed_o[9:8] src_op_ed_e[9:8]
	WriteData(0x21);
	WriteComm(0x63);//src_op_ed_o[7:0]
	WriteData(0x07);
	WriteComm(0x64);//src_op_ed_e[7:0]
	WriteData(0xe0);
	WriteComm(0x65);//chopper
	WriteData(0x01);//01-A2,02--A1NVu NV3041A-01

	//WriteComm(0x67);
	//WriteData(0x33);//01
	WriteComm(0xca); //avdd_mux_st_o[7:0]
	WriteData(0x20);
	WriteComm(0xcb); //avdd_mux_ed_o[7:0]
	WriteData(0x52);
	WriteComm(0xcc); //avdd_mux_st_e[7:0]
	WriteData(0x10);
	WriteComm(0xcD); //avdd_mux_ed_e[7:0]
	WriteData(0x42);
	WriteComm(0xD0); //avcl_mux_st_o[7:0]
	WriteData(0x20);
	WriteComm(0xD1); //avcl_mux_ed_o[7:0]
	WriteData(0x52);
	WriteComm(0xD2); //avcl_mux_st_e[7:0]
	WriteData(0x10);
	WriteComm(0xD3); //avcl_mux_ed_e[7:0]
	WriteData(0x42);
	WriteComm(0xD4); //vgh_mux_st[7:0]
	WriteData(0x0a);
	WriteComm(0xD5); //vgh_mux_ed[7:0]
	WriteData(0x32);
	WriteComm(0xe5); //DVDD_TRIM
	WriteData(0x05); //1.65 05
	WriteComm(0xe6); //ESD_CTRL
	WriteData(0x00);
	WriteComm(0x6e); //LVD_en
	WriteData(0x14);
	//gammma 01
	WriteComm(0x80); //gam_vrp0 63
	WriteData(0x04);
	WriteComm(0xA0); //gam_VRN0 63
	WriteData(0x00);
	WriteComm(0x81); //gam_vrp1 62
	WriteData(0x07);
	WriteComm(0xA1); //gam_VRN1 62-
	WriteData(0x05);
	WriteComm(0x82); //gam_vrp2 61
	WriteData(0x06);
	WriteComm(0xA2); //gam_VRN2 61-NVu NV3041A-01

	WriteData(0x04);
	WriteComm(0x83); //gam_vrp3 2
	WriteData(0x39);
	WriteComm(0xA3); //gam_VRN3 2-
	WriteData(0x39);
	WriteComm(0x84); //gam_vrp4 1
	WriteData(0x3a);
	WriteComm(0xA4); //gam_VRN4 1-
	WriteData(0x3a);
	WriteComm(0x85); //gam_vrp5 0
	WriteData(0x3f); //2a~39-0.43
	WriteComm(0xA5); //gam_VRN5 0-
	WriteData(0x3f);
	WriteComm(0x86); //gam_prp0 50
	WriteData(0x2c); //33
	WriteComm(0xA6); //gam_PRN0 50-
	WriteData(0x2a); //2a
	//WriteComm(0x87); //gam_prp1 14
	//WriteData(0x46); //2d
	//WriteComm(0xA7); //gam_PRN1 14-
	//WriteData(0x44); //2d
	WriteComm(0x87); //gam_prp1 14
	WriteData(0x43); //2d
	WriteComm(0xA7); //gam_PRN1 14-
	WriteData(0x47); //2d
	WriteComm(0x88); //gam_pkp0 59
	WriteData(0x08); //0b
	WriteComm(0xA8); //gam_PKN0 59-
	WriteData(0x08); //0b
	WriteComm(0x89); //gam_pkp1 57
	WriteData(0x0f); //14
	WriteComm(0xA9); //gam_PKN1 57-
	WriteData(0x0f); //14
	WriteComm(0x8a); //gam_pkp2 54
	WriteData(0x17); //1a
	WriteComm(0xAa); //gam_PKN2 54-
	WriteData(0x17); //1a
	WriteComm(0x8b); //gam_PKP3 44
	WriteData(0x10);
	WriteComm(0xAb); //gam_PKN3 44-
	WriteData(0x10);
	WriteComm(0x8c); //gam_PKP4 38
	WriteData(0x16);
	WriteComm(0xAc); //gam_PKN4 38-
	WriteData(0x16);//NVu NV3041A-01

	WriteComm(0x8d); //gam_PKP5 32
	WriteData(0x14);
	WriteComm(0xAd); //gam_PKN5 32-
	WriteData(0x14);
	WriteComm(0x8e); //gam_PKP6 26
	WriteData(0x11); //16
	WriteComm(0xAe); //gam_PKN6 26-
	WriteData(0x11); //13
	WriteComm(0x8f); //gam_PKP7 20
	WriteData(0x14); //1c
	WriteComm(0xAf); //gam_PKN7 20-
	WriteData(0x14); //0a
	WriteComm(0x90); //gam_PKP8 10
	WriteData(0x06);
	WriteComm(0xB0); //gam_PKN8 10-
	WriteData(0x06);
	WriteComm(0x91); //gam_PKP9 6
	WriteData(0x0f);
	WriteComm(0xB1); //gam_PKN9 6-
	WriteData(0x0f);
	WriteComm(0x92); //gam_PKP10 4
	WriteData(0x16);
	WriteComm(0xB2); //gam_PKN10 4-
	WriteData(0x16);
	WriteComm(0xff);
	WriteData(0x00);
	WriteComm(0x11);
	
 	WriteComm(0x36);
 	WriteData(0x00);
	
	system_delay_us(120*1000);
	WriteComm(0x29);
	system_delay_us(20*1000);
	
	#else
	WriteComm(0xff);
	WriteData(0xa5);
	WriteComm(0xE7); //TE_output_en
	WriteData(0x10);
	WriteComm(0x35); //TE_ interface_en
	WriteData(0x00);//01
	WriteComm(0x36);
	WriteData(0xc0);
	WriteComm(0x3A);
	WriteData(0x01);//01---565/00---666
	WriteComm(0x40);
	WriteData(0x01);//01:IPS/00:TN
	WriteComm(0x41);
	WriteData(0x03);//01--8bit/03--16bit
	WriteComm(0x44); //VBP
	WriteData(0x15); //21
	WriteComm(0x45); //VFP
	WriteData(0x15); //21
	WriteComm(0x7d);//vdds_trim[2:0]
	WriteData(0x03);
	WriteComm(0xc1);//avdd_clp_en avdd_clp[1:0] avcl_clp_en avcl_clp[1:0]
	WriteData(0xbb);//0xbb 88 a2
	WriteComm(0xc2);//vgl_clp_en vgl_clp[2:0]
	WriteData(0x05);
	WriteComm(0xc3);//vgl_clp_en vgl_clp[2:0]
	WriteData(0x10);
	WriteComm(0xc6);//avdd_ratio_sel avcl_ratio_sel vgh_ratio_sel[1:0] vgl_ratio_sel[1:0]
	WriteData(0x3e); // 35
	WriteComm(0xc7);//mv_clk_sel[1:0] avdd_clk_sel[1:0] avcl_clk_sel[1:0]
	WriteData(0x25); //2e
	WriteComm(0xc8);// VGL_CLK_sel
	WriteData(0x21); //
	WriteComm(0x7a);// user_vgsp
	WriteData(0x58);
	WriteComm(0x6f);// user_gvdd
	WriteData(0x4F);
	WriteComm(0x78);// user_gvcl
	WriteData(0x70);
	WriteComm(0xc9);//
	WriteData(0x00);
	WriteComm(0x67);
	WriteData(0x11);
	//gate_ed
	WriteComm(0x51);//gate_st_o[7:0]
	WriteData(0x0a);
	WriteComm(0x52);//gate_ed_o[7:0]
	WriteData(0x7a); //76
	WriteComm(0x53);//gate_st_e[7:0]
	WriteData(0x0a); //76
	WriteComm(0x54);//gate_ed_e[7:0]
	WriteData(0x7a);

	WriteComm(0x46);//fsm_hbp_o[5:0]
	WriteData(0x0a);
	WriteComm(0x47);//fsm_hfp_o[5:0]
	WriteData(0x2a);
	WriteComm(0x48);//fsm_hbp_e[5:0]
	WriteData(0x0a);
	WriteComm(0x49);//fsm_hfp_e[5:0]
	WriteData(0x1a);
	WriteComm(0x44); //VBP
	WriteData(0x15); //21
	WriteComm(0x45); //VFP
	WriteData(0x15); //21
	WriteComm(0x73);
	WriteData(0x08);
	WriteComm(0x74);
	WriteData(0x0a);
	WriteComm(0x56);//src_ld_wd[1:0] src_ld_st[5:0]
	WriteData(0x43);
	WriteComm(0x57);//pn_cs_en src_cs_st[5:0]
	WriteData(0x42);
	WriteComm(0x58);//src_cs_p_wd[6:0]
	WriteData(0x3c);
	WriteComm(0x59);//src_cs_n_wd[6:0]
	WriteData(0x64);
	WriteComm(0x5a);//src_pchg_st_o[6:0]
	WriteData(0x41); //41
	WriteComm(0x5b);//src_pchg_wd_o[6:0]
	WriteData(0x3C);
	WriteComm(0x5c);//src_pchg_st_e[6:0]
	WriteData(0x02); //02
	WriteComm(0x5d);//src_pchg_wd_e[6:0]
	WriteData(0x3c); //3c
	WriteComm(0x5e);//src_pol_sw[7:0]
	WriteData(0x1f);
	WriteComm(0x60);//src_op_st_o[7:0]
	WriteData(0x80);
	WriteComm(0x61);//src_op_st_e[7:0]
	WriteData(0x3f);
	WriteComm(0x62);//src_op_ed_o[9:8] src_op_ed_e[9:8]
	WriteData(0x21);
	WriteComm(0x63);//src_op_ed_o[7:0]
	WriteData(0x07);
	WriteComm(0x64);//src_op_ed_e[7:0]
	WriteData(0xe0);
	WriteComm(0x65);//chopper
	WriteData(0x02);
	WriteComm(0xca); //avdd_mux_st_o[7:0]
	WriteData(0x20);
	WriteComm(0xcb); //avdd_mux_ed_o[7:0]
	WriteData(0x52); //52
	WriteComm(0xcc); //avdd_mux_st_e[7:0]
	WriteData(0x10);
	WriteComm(0xcD); //avdd_mux_ed_e[7:0]
	WriteData(0x42);
	WriteComm(0xD0); //avcl_mux_st_o[7:0]
	WriteData(0x20);
	WriteComm(0xD1); //avcl_mux_ed_o[7:0]
	WriteData(0x52);
	WriteComm(0xD2); //avcl_mux_st_e[7:0]
	WriteData(0x10);
	WriteComm(0xD3); //avcl_mux_ed_e[7:0]
	WriteData(0x42);
	WriteComm(0xD4); //vgh_mux_st[7:0]
	WriteData(0x0a);
	WriteComm(0xD5); //vgh_mux_ed[7:0]
	WriteData(0x32);
	///test mode
	WriteComm(0xf8);
	WriteData(0x03);
	WriteComm(0xf9);
	WriteData(0x20);
	WriteComm(0x80); //gam_vrp0
	WriteData(0x00);
	WriteComm(0xA0); //gam_VRN0
	WriteData(0x00);
	WriteComm(0x81); //gam_vrp1
	WriteData(0x07);
	WriteComm(0xA1); //gam_VRN1
	WriteData(0x06);
	WriteComm(0x82); //gam_vrp2
	WriteData(0x02);
	WriteComm(0xA2); //gam_VRN2
	WriteData(0x01);
	WriteComm(0x86); //gam_prp0
	WriteData(0x11); //33
	WriteComm(0xA6); //gam_PRN0
	WriteData(0x10); //2a
	WriteComm(0x87); //gam_prp1
	WriteData(0x27); //2d
	WriteComm(0xA7); //gam_PRN1
	WriteData(0x27); //2d
	WriteComm(0x83); //gam_vrp3
	WriteData(0x37);
	WriteComm(0xA3); //gam_VRN3
	WriteData(0x37);
	WriteComm(0x84); //gam_vrp4
	WriteData(0x35);
	WriteComm(0xA4); //gam_VRN4
	WriteData(0x35);
	WriteComm(0x85); //gam_vrp5
	WriteData(0x3f);
	WriteComm(0xA5); //gam_VRN5
	WriteData(0x3f);
	WriteComm(0x88); //gam_pkp0
	WriteData(0x0b); //0b
	WriteComm(0xA8); //gam_PKN0
	WriteData(0x0b); //0b
	WriteComm(0x89); //gam_pkp1
	WriteData(0x14); //14
	WriteComm(0xA9); //gam_PKN1
	WriteData(0x13); //14
	WriteComm(0x8a); //gam_pkp2
	WriteData(0x1a); //1a
	WriteComm(0xAa); //gam_PKN2
	WriteData(0x1a); //1a
	WriteComm(0x8b); //gam_PKP3
	WriteData(0x0a);
	WriteComm(0xAb); //gam_PKN3
	WriteData(0x0a);
	WriteComm(0x8c); //gam_PKP4
	WriteData(0x14);
	WriteComm(0xAc); //gam_PKN4
	WriteData(0x08);
	WriteComm(0x8d); //gam_PKP5
	WriteData(0x17);
	WriteComm(0xAd); //gam_PKN5
	WriteData(0x07);
	WriteComm(0x8e); //gam_PKP6
	WriteData(0x16); //16
	WriteComm(0xAe); //gam_PKN6
	WriteData(0x06); //13
	WriteComm(0x8f); //gam_PKP7
	WriteData(0x1b); //1c
	WriteComm(0xAf); //gam_PKN7
	WriteData(0x07); //0a
	WriteComm(0x90); //gam_PKP8
	WriteData(0x04);
	WriteComm(0xB0); //gam_PKN8
	WriteData(0x04);
	WriteComm(0x91); //gam_PKP9
	WriteData(0x0a);
	WriteComm(0xB1); //gam_PKN9
	WriteData(0x0a);
	WriteComm(0x92); //gam_PKP10
	WriteData(0x16);
	WriteComm(0xB2); //gam_PKN10
	WriteData(0x15);
	WriteComm(0xff);
	WriteData(0x00);
	WriteComm(0x11);
	WriteData(0x00);
	system_delay_us(700*1000);
	WriteComm(0x29);
	WriteData(0x00);
	#endif
	
	// LCD_READ_DATA(0x36);
//	for(uint32_t i=0;i<pixel_size;i++)
//	{
//		color_buffer[i]=0xf800;
//	}
//	nv3041a_set_window(0,240-1,0,320-1);
//	__PARALLEL_CS_SET(hparallel.PARALLELx);
//	/* writer data */   
//	Parallel_write_data(&hparallel,(uint32_t *)&color_buffer,(pixel_size));
//	__PARALLEL_CS_RELEASE(hparallel.PARALLELx);	
//	system_delay_us(2000*1000);
	#if 1
	for(uint32_t i=0;i<pixel_size;i++)
	{
		color_buffer[i]=0xf800;
	}
	nv3041a_set_window(0,100-1,0,100-1);
	__PARALLEL_CS_SET(hparallel.PARALLELx);
	/* writer data */   
	Parallel_write_data(&hparallel,(uint32_t *)&color_buffer,(pixel_size));
	system_delay_us(100);
	__PARALLEL_CS_RELEASE(hparallel.PARALLELx);	
	system_delay_us(1000*1000);
	
	#if 0
	extern uint32_t *user_get_display_framebuffer(void);
	uint16_t *buf = (uint16_t*)user_get_display_framebuffer();
	
	nv3041a_set_window(0,100-1,0,100-1);
	for(uint32_t i=0;i<pixel_size;i++)
	{
		color_buffer[i]=0x001f;
	}
	nv3041a_display_dma(pixel_size,16,color_buffer);
	
 	system_delay_us(2000*1000);
	uint16_t color_buf[16]={
	0xf800,0x001f,0x01e0,0xffff,0x0fff,
	};
	static uint8_t index=0;
	while(1)
	{
		for(uint32_t i=0;i<480*272;i++)
		{
			buf[i]=color_buf[index];
		}
		++index;
		index%=4;
		nv3041a_set_window(0,480-1,0,272-1);
		nv3041a_display_dma((480*272),16,buf);
		system_delay_us(2000*1000);
		if(index==0)break;
	}
	
	for(uint32_t i=0;i<480*272;i++)
	{
		buf[i]=0xf800;
	}
	nv3041a_set_window(0,480-1,0,272-1);
	nv3041a_display_dma((480*272),16,buf);
	system_delay_us(2000*1000);
	#endif
//	LCD_Fill(0,0,240,320,0x001f);
//	system_delay_us(2000*1000);
//	LCD_Fill(0,0,240,320,0x01e0);
//		system_delay_us(2000*1000);
//	LCD_Fill(0,0,240,320,0xffff);
	printf("LCD_Fill\r\n");
	display_backlight_set();
	#endif
	
}
 
#endif


